package com.music.note_android.ui.editor

import android.graphics.Color
import android.graphics.PointF
import android.os.SystemClock
import android.util.Log
import kotlinx.coroutines.*
import kotlin.math.cos
import kotlin.math.sin
import kotlin.random.Random

/**
 * 画布性能基准测试工具
 * 用于评估画布在不同场景下的性能表现
 */
class CanvasBenchmark {
    
    companion object {
        private const val TAG = "CanvasBenchmark"
        private const val WARMUP_ITERATIONS = 10
        private const val BENCHMARK_ITERATIONS = 100
    }
    
    /**
     * 基准测试结果
     */
    data class BenchmarkResult(
        val testName: String,
        val averageTime: Double,
        val minTime: Long,
        val maxTime: Long,
        val totalTime: Long,
        val iterations: Int,
        val throughput: Double // 每秒操作数
    )
    
    /**
     * 基准测试回调
     */
    interface BenchmarkCallback {
        fun onBenchmarkStarted(testName: String)
        fun onBenchmarkProgress(progress: Int)
        fun onBenchmarkCompleted(result: BenchmarkResult)
        fun onBenchmarkFailed(testName: String, error: String)
    }
    
    /**
     * 运行绘制性能基准测试
     */
    suspend fun runDrawingBenchmark(
        canvasView: DrawingCanvasView,
        callback: BenchmarkCallback
    ) = withContext(Dispatchers.Main) {
        try {
            callback.onBenchmarkStarted("绘制性能基准测试")
            
            // 预热
            repeat(WARMUP_ITERATIONS) {
                performDrawingOperation(canvasView)
                delay(10)
            }
            
            // 基准测试
            val times = mutableListOf<Long>()
            val startTime = SystemClock.elapsedRealtime()
            
            repeat(BENCHMARK_ITERATIONS) { iteration ->
                val operationStartTime = SystemClock.elapsedRealtimeNanos()
                
                performDrawingOperation(canvasView)
                
                val operationEndTime = SystemClock.elapsedRealtimeNanos()
                times.add((operationEndTime - operationStartTime) / 1_000_000) // 转换为毫秒
                
                val progress = ((iteration + 1) * 100) / BENCHMARK_ITERATIONS
                callback.onBenchmarkProgress(progress)
                
                delay(5) // 短暂延迟避免过度占用CPU
            }
            
            val endTime = SystemClock.elapsedRealtime()
            val totalTime = endTime - startTime
            
            val result = BenchmarkResult(
                testName = "绘制性能基准测试",
                averageTime = times.average(),
                minTime = times.minOrNull() ?: 0L,
                maxTime = times.maxOrNull() ?: 0L,
                totalTime = totalTime,
                iterations = BENCHMARK_ITERATIONS,
                throughput = (BENCHMARK_ITERATIONS * 1000.0) / totalTime
            )
            
            callback.onBenchmarkCompleted(result)
            
        } catch (e: Exception) {
            callback.onBenchmarkFailed("绘制性能基准测试", e.message ?: "未知错误")
        }
    }
    
    /**
     * 运行缩放性能基准测试
     */
    suspend fun runScalingBenchmark(
        canvasView: DrawingCanvasView,
        callback: BenchmarkCallback
    ) = withContext(Dispatchers.Main) {
        try {
            callback.onBenchmarkStarted("缩放性能基准测试")
            
            // 预热
            repeat(WARMUP_ITERATIONS) {
                performScalingOperation(canvasView)
                delay(10)
            }
            
            // 基准测试
            val times = mutableListOf<Long>()
            val startTime = SystemClock.elapsedRealtime()
            
            repeat(BENCHMARK_ITERATIONS) { iteration ->
                val operationStartTime = SystemClock.elapsedRealtimeNanos()
                
                performScalingOperation(canvasView)
                
                val operationEndTime = SystemClock.elapsedRealtimeNanos()
                times.add((operationEndTime - operationStartTime) / 1_000_000)
                
                val progress = ((iteration + 1) * 100) / BENCHMARK_ITERATIONS
                callback.onBenchmarkProgress(progress)
                
                delay(5)
            }
            
            val endTime = SystemClock.elapsedRealtime()
            val totalTime = endTime - startTime
            
            val result = BenchmarkResult(
                testName = "缩放性能基准测试",
                averageTime = times.average(),
                minTime = times.minOrNull() ?: 0L,
                maxTime = times.maxOrNull() ?: 0L,
                totalTime = totalTime,
                iterations = BENCHMARK_ITERATIONS,
                throughput = (BENCHMARK_ITERATIONS * 1000.0) / totalTime
            )
            
            callback.onBenchmarkCompleted(result)
            
        } catch (e: Exception) {
            callback.onBenchmarkFailed("缩放性能基准测试", e.message ?: "未知错误")
        }
    }
    
    /**
     * 运行橡皮擦性能基准测试
     */
    suspend fun runEraserBenchmark(
        canvasView: DrawingCanvasView,
        callback: BenchmarkCallback
    ) = withContext(Dispatchers.Main) {
        try {
            callback.onBenchmarkStarted("橡皮擦性能基准测试")
            
            // 先绘制一些内容供擦除
            repeat(50) {
                performDrawingOperation(canvasView)
            }
            
            // 切换到橡皮擦工具
            canvasView.setCurrentTool(DrawingTool.ERASER)
            
            // 预热
            repeat(WARMUP_ITERATIONS) {
                performEraserOperation(canvasView)
                delay(10)
            }
            
            // 基准测试
            val times = mutableListOf<Long>()
            val startTime = SystemClock.elapsedRealtime()
            
            repeat(BENCHMARK_ITERATIONS) { iteration ->
                val operationStartTime = SystemClock.elapsedRealtimeNanos()
                
                performEraserOperation(canvasView)
                
                val operationEndTime = SystemClock.elapsedRealtimeNanos()
                times.add((operationEndTime - operationStartTime) / 1_000_000)
                
                val progress = ((iteration + 1) * 100) / BENCHMARK_ITERATIONS
                callback.onBenchmarkProgress(progress)
                
                delay(5)
            }
            
            val endTime = SystemClock.elapsedRealtime()
            val totalTime = endTime - startTime
            
            val result = BenchmarkResult(
                testName = "橡皮擦性能基准测试",
                averageTime = times.average(),
                minTime = times.minOrNull() ?: 0L,
                maxTime = times.maxOrNull() ?: 0L,
                totalTime = totalTime,
                iterations = BENCHMARK_ITERATIONS,
                throughput = (BENCHMARK_ITERATIONS * 1000.0) / totalTime
            )
            
            callback.onBenchmarkCompleted(result)
            
        } catch (e: Exception) {
            callback.onBenchmarkFailed("橡皮擦性能基准测试", e.message ?: "未知错误")
        }
    }
    
    /**
     * 执行绘制操作
     */
    private fun performDrawingOperation(canvasView: DrawingCanvasView) {
        // 生成随机笔画
        val startX = Random.nextFloat() * 500 + 100
        val startY = Random.nextFloat() * 500 + 100
        val points = generateRandomStrokePoints(startX, startY, 20)
        
        // 模拟绘制过程
        // 注意：这里应该调用实际的绘制方法，但由于需要访问私有方法，这里简化处理
        canvasView.invalidate()
    }
    
    /**
     * 执行缩放操作
     */
    private fun performScalingOperation(canvasView: DrawingCanvasView) {
        // 模拟缩放手势
        val scaleFactor = 1.0f + (Random.nextFloat() - 0.5f) * 0.2f
        val focusX = canvasView.width / 2f
        val focusY = canvasView.height / 2f
        
        // 这里应该调用实际的缩放方法
        canvasView.invalidate()
    }
    
    /**
     * 执行橡皮擦操作
     */
    private fun performEraserOperation(canvasView: DrawingCanvasView) {
        // 生成随机擦除位置
        val x = Random.nextFloat() * canvasView.width
        val y = Random.nextFloat() * canvasView.height
        
        // 这里应该调用实际的擦除方法
        canvasView.invalidate()
    }
    
    /**
     * 生成随机笔画点
     */
    private fun generateRandomStrokePoints(startX: Float, startY: Float, count: Int): List<PointF> {
        val points = mutableListOf<PointF>()
        var currentX = startX
        var currentY = startY
        
        repeat(count) {
            points.add(PointF(currentX, currentY))
            currentX += (Random.nextFloat() - 0.5f) * 20
            currentY += (Random.nextFloat() - 0.5f) * 20
        }
        
        return points
    }
    
    /**
     * 生成螺旋形笔画点
     */
    private fun generateSpiralStrokePoints(centerX: Float, centerY: Float, count: Int): List<PointF> {
        val points = mutableListOf<PointF>()
        
        repeat(count) { i ->
            val angle = i * 0.2f
            val radius = i * 2f
            val x = centerX + cos(angle) * radius
            val y = centerY + sin(angle) * radius
            points.add(PointF(x, y))
        }
        
        return points
    }
    
    /**
     * 打印基准测试结果
     */
    fun printBenchmarkResult(result: BenchmarkResult) {
        Log.i(TAG, "=== ${result.testName} 结果 ===")
        Log.i(TAG, "平均时间: ${String.format("%.2f", result.averageTime)} ms")
        Log.i(TAG, "最小时间: ${result.minTime} ms")
        Log.i(TAG, "最大时间: ${result.maxTime} ms")
        Log.i(TAG, "总时间: ${result.totalTime} ms")
        Log.i(TAG, "迭代次数: ${result.iterations}")
        Log.i(TAG, "吞吐量: ${String.format("%.2f", result.throughput)} ops/sec")
        Log.i(TAG, "==============================")
    }
}